package org.grayrabbit.cloud.utils.manager;

import java.io.File;
import java.io.IOException;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Date;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cloud.core.Constants;
import org.grayrabbit.cloud.core.biz.BizResult;
import org.grayrabbit.cloud.core.biz.ClientUtility;
import org.grayrabbit.cloud.core.biz.ObjectArgument;
import org.grayrabbit.cloud.core.rpc.Argument;
import org.grayrabbit.cloud.core.rpc.Result;
import org.grayrabbit.cloud.utils.CommandBuilder;
import org.grayrabbit.cloud.utils.logger.LoggerWrapper;
import org.grayrabbit.cloud.utils.logger.Output;


public class LocalCommandHandler extends AbstractCommandHandler{

//	private boolean rpcServer = true;
	
	public LocalCommandHandler(Output out,boolean rpcServer) {
		super(out);		
//		this.rpcServer = rpcServer;
	}

	public void handler(String command) {
	
		try{
			
			if(StringUtils.isBlank(command)){
				out.writeln(command+":command not found");
			}else{
				
				StringTokenizer toker = new StringTokenizer (command);
				String cmd = toker.nextToken();
				
				if(cmd.equalsIgnoreCase("help")){
					out.writeln("============== Command Processor v1.01 ==============");				
					out.writeln("logger [-p]");
					out.writeln("system [-p]");
					out.writeln("version");
		        	out.writeln("quit/exit");
		        	out.writeln("=============================================");
				}else if(cmd.equalsIgnoreCase("logger") || cmd.equalsIgnoreCase("log")){
					
					String arg = "";
					if(toker.hasMoreTokens())	arg = toker.nextToken();
					if(arg.equalsIgnoreCase("--help") || 
					   arg.equalsIgnoreCase("-help")  ||
					   arg.equalsIgnoreCase("/help")){
						
						out.writeln("Usage:logger{log} [option] [parameter]");				
						out.writeln("Summary:print log message,set log-level");
						out.writeln("Detail:");
						out.writeln("-l,-level [0..9]	set log-level");
						out.writeln("           0:ALL,1:DEBUG,2:INFO(default),3:WARN,4:ERROR,5:FATAL,9:OFF");
						
					}
					else if(arg.equalsIgnoreCase("-l") || arg.equalsIgnoreCase("-level")){
						
						String param = "2";
						if(toker.hasMoreTokens())	arg = toker.nextToken();
						LoggerWrapper.setBaseRootLevel(Integer.parseInt(param)*10000);							
					}
					
				}else if(cmd.equalsIgnoreCase("system") || cmd.equalsIgnoreCase("sys")){
					
					String arg = "";
					if(toker.hasMoreTokens())	arg = toker.nextToken();
					if(arg.equalsIgnoreCase("--help") || 
					   arg.equalsIgnoreCase("-help")  ||
					   arg.equalsIgnoreCase("/help")){
						
						out.writeln("用法:system{sys} [option] [parameter]");				
						out.writeln("摘要：打印内存状态,执行垃圾回收，打印系统内核，打印JVM运行环境，打印磁盘空间，打印线程信息等");
						out.writeln("详细：");
						out.writeln("-m,-mem 显示内存状态");
						out.writeln("-runtime ,-run JVM运行环境信息");	
						out.writeln("-uname 显示服务器内核信息");
						out.writeln("-classload  显示类加载情况");
						out.writeln("-compilation,-compile  显示编译器的信息");
						out.writeln("-disk  显示服务器磁盘空间信息");
						out.writeln("-thread [ID]  显示服务器JVM线程信息，有ID参数则显示该ID线程的详细信息");
						out.writeln("-gc,-clear 执行垃圾回收");						
					}
					else if(arg.equalsIgnoreCase("-m") || arg.equalsIgnoreCase("-mem")){
						
						String module = null;
						if(toker.hasMoreTokens())	module = toker.nextToken();
						
						if(module==null){
							MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
							out.writeln(
									String.format("堆内存情况(HEAP):used=%dkb,init=%dkb,max=%dkb",
			            			(mem.getHeapMemoryUsage().getUsed()/1024),		
			            			mem.getHeapMemoryUsage().getInit()/1024,
			            			mem.getHeapMemoryUsage().getMax()/1024));
							out.writeln(
									String.format("非堆内存情况(NOT HEAP):used=%dkb,init=%dkb,max=%dkb",
			            			(mem.getNonHeapMemoryUsage().getUsed()/1024),		
			            			mem.getNonHeapMemoryUsage().getInit()/1024,
			            			mem.getNonHeapMemoryUsage().getMax()/1024));
							out.writeln(String.format("待挂起回收对象数:%d",mem.getObjectPendingFinalizationCount()));
							
						}else{
							
							String outstr = "do nothing";	
							
							try{
								String param = CommandBuilder.SystemCommand("mem", module);
								ObjectArgument argument = new ObjectArgument(param);
								Result result = submit(module, argument);
								if(result instanceof BizResult)
									outstr = String.valueOf(((BizResult)result).getResult());
							}catch(Exception e){
								outstr = "exception for module "+module + ":" + e.getMessage();
							}
							
							out.writeln(outstr);
						}
						
					}
					else if(arg.equalsIgnoreCase("-gc") || arg.equalsIgnoreCase("-clear")){
					
						String module = null;
						if(toker.hasMoreTokens())	module = toker.nextToken();
						
						if(module==null){
							
							Runtime.getRuntime().gc();
							out.writeln("gc succeed");
							
						}else{
							
							String outstr = "do nothing";	
							
							try{
								String param = CommandBuilder.SystemCommand("gc", module);
								ObjectArgument argument = new ObjectArgument(param);
								Result result = submit(module, argument);
								outstr = result.equals(BizResult.TRUE)?"gc for module "+module+"succeed":"gc for module "+module+"failure";
							}catch(Exception e){
								outstr = "exception for module "+module+ ":" + e.getMessage();
							}
							
							out.writeln(outstr);
						}
						
					}else if(arg.equalsIgnoreCase("-uname")){
						OperatingSystemMXBean osm = ManagementFactory.getOperatingSystemMXBean();
						out.writeln(String.format("操作系统:%s,版本：%s,系统内核:%s,CPU数:%d,系统负载:%f", 
								osm.getName(),
								osm.getVersion(),
								osm.getArch(),
								osm.getAvailableProcessors(),
								osm.getSystemLoadAverage()));
					}else if(arg.equalsIgnoreCase("-runtime")||arg.equalsIgnoreCase("-run")){
						RuntimeMXBean rm = ManagementFactory.getRuntimeMXBean();
						out.writeln(String.format("名称:%s,规范：%s,供应商:%s,版本:%s,规范管理API版本:%s,VM名称:%s,VM供应商:%s,VM版本:%s,启动时间：%tY-%9$tm-%9$te %9$tH:%9$tM:%9$tS,运行时长:%ds,BootClassPath:%s,ClassPath:%s,Library:%s,启动参数:%s", 
								rm.getName(),
								rm.getSpecName(),
								rm.getSpecVendor(),
								rm.getSpecVersion(),
								rm.getManagementSpecVersion(),
								rm.getVmName(),
								rm.getVmVendor(),
								rm.getVmVersion(),
								 new Date(rm.getStartTime()),
								rm.getUptime()/1000,
								rm.getBootClassPath(),
								rm.getClassPath(),
								rm.getLibraryPath(),
								rm.getInputArguments()
								));
					}else if(arg.equalsIgnoreCase("-classload")){
						ClassLoadingMXBean clm = ManagementFactory.getClassLoadingMXBean();
						out.writeln(String.format("总加载类数量:%d,当前类加载数量:%d,总卸载数量：%d", 
								clm.getTotalLoadedClassCount(),
								clm.getLoadedClassCount(),
								clm.getUnloadedClassCount()
								));
					}else if(arg.equalsIgnoreCase("-compilation")||arg.equalsIgnoreCase("-compile")){
						CompilationMXBean cm = ManagementFactory.getCompilationMXBean();
						out.writeln(String.format("编译器:%s,总编译时长:%ds", 
								cm.getName(),
								cm.getTotalCompilationTime()/1000
								));
					}else if(arg.equalsIgnoreCase("-disk")){
						File[] fs = File.listRoots();
						for(File f : fs){
						out.writeln(String.format("路径:%s,总容量:%dkb,可用空间:%dkb,已用空间:%dkb", 
								f.getPath(),
								f.getTotalSpace()/1024,
								f.getFreeSpace()/1024,
								f.getUsableSpace()/1024
								));
						}
					}else if(arg.equalsIgnoreCase("-thread")){
						ThreadMXBean tm = ManagementFactory.getThreadMXBean();
						String module = null;
						if(toker.hasMoreTokens())	
							module = toker.nextToken();
						if(module==null){
							out.writeln(String.format("总线程数:%d,守护线程数：%d,非守护线程数:%d,初始化线程数:%d,线程数峰值:%d", 
									tm.getThreadCount(),
									tm.getDaemonThreadCount(),
									tm.getThreadCount()-tm.getDaemonThreadCount(),
									tm.getTotalStartedThreadCount(),
									tm.getPeakThreadCount()
									));
							long[] threads = tm.getAllThreadIds();
							out.writeln("当前所有线程:");
							for(long th : threads){
								out.writeln(String.format("THREAD ID:%d",th));
							}
						}else{
							long thid = Long.parseLong(module);
							ThreadInfo thInfo = tm.getThreadInfo(thid);
							out.writeln(String.format("线程ID:%d,名称：%s,状态:%s,等待次数:%d,等待时长:%dms,阻塞次数:%d,阻塞时长:%dms,锁定名称:%s,锁定线程ID:%d,锁定线程名:%s",
									thInfo.getThreadId(),
									thInfo.getThreadName(),
									thInfo.getThreadState(),
									thInfo.getWaitedCount(),
									thInfo.getWaitedTime(),
									thInfo.getBlockedCount(),
									thInfo.getBlockedTime(),
									thInfo.getLockName(),
									thInfo.getLockOwnerId(),
									thInfo.getLockOwnerName()
									));
						}
					}
					
				}else if(cmd.equalsIgnoreCase("version") || cmd.equalsIgnoreCase("ver")){
					out.writeln(Constants.getVersion());
				}else{
					out.writeln(command+":command not found");
				}
				
			}
			
		
		}catch(IOException e){
			e.printStackTrace();
		}catch (Exception e) {
			try {
				out.writeln("命令执行异常，请重试！help 显示命令信息");
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		
	}
	
	private Result submit(String module,Argument argument) throws Exception{
//		if(rpcServer)
			return ClientUtility.submit(module,argument);
//		else{
//			BizAsyncRouter gate = new BizAsyncRouter(com.intohotel.core.client.ClientInvoker.ASYNC_ROUNTER);
//			return gate.submit(argument);
//		}
	}
	
}
